//异步缓冲区类
#ifndef _M_BUFFER_H__
#define _M_BUFFER_H__

#include<iostream>
#include<condition_variable>
#include<memory>
#include<mutex>
#include<vector>
#include<assert.h>
using namespace std;

namespace bitlog{
    #define BUFFER_DEFAULT_SIZE (1*1024*1024)
    #define BUFFER_INCREMENT_SIZE (1*1024*1024)
    #define BUFFER_THRESHOLD_SIZE (10*1024*1024)
    class Buffer{
        public:
        Buffer():_read_idx(0),_write_idx(0),_v(BUFFER_DEFAULT_SIZE)
        {}
        bool empty(){
            return _write_idx==_read_idx;
        }
        size_t readAblesize(){
            return _write_idx-_read_idx;
        }
        size_t writeAblesize(){
            return _v.size()-_write_idx;
        }
        const char* begin(){
            return &_v[_read_idx];
        }
        void swap(Buffer &buf) {
            _v.swap(buf._v);
            std::swap(_read_idx, buf._read_idx);
            std::swap(_write_idx, buf._write_idx);
        }
        void reset(){
            _write_idx=_read_idx=0;
        }
        void push(const char* data,size_t len){
            // assert(len<=writeAblesize());
            ensureEnoughspace(len);
            std::copy(data,data+len,&_v[_write_idx]);
            _write_idx+=len;

         //   std::cout << "_write_index : " << _write_idx << std::endl;
        }
        void pop(size_t len){
            _read_idx+=len;
            assert(_read_idx<=_write_idx);

            if(_read_idx==_write_idx){
                reset();
            }

        }
        protected:
        void ensureEnoughspace(size_t len){
            if(len<=writeAblesize()) return;
            size_t new_capacity;
            if(_v.size()<BUFFER_THRESHOLD_SIZE){
                new_capacity=_v.size()*2+len;
            }else{
                new_capacity=_v.size()+BUFFER_INCREMENT_SIZE+len;
            }
            _v.resize(new_capacity);
        }
        private:
        size_t _read_idx;
        size_t _write_idx;
        vector<char> _v;
    };
}


#endif